#region Summary

// 
// Owner : JackieHan 
// 
// Solution : LearnSolution 
// 
// Project : JackieHan.NHibernate3.Configuration
// 
// File : NHibernateHelper.cs
// 
// CopyRight : Copyright © 2010-2011 Skomart Corporation, All Rights Reserved 
// 
// Summary : NHibernate Helper类
// 
// History : 
//			2010-09-14 11:41:36	    Create 
// 

#endregion

#region Using

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using ConfOrm;
using ConfOrm.NH;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Cfg.MappingSchema;

#endregion

namespace JackieHan.NHibernate3.Repository
{
    /// <summary> 
    /// NHibernate Helper类
    /// </summary>
    public class NHSessionFactory
    {
        private static ISessionFactory sessionFactory;
        private static readonly object lockObj = new object();
        private static IInitializeNHConfiguration initializeManager;

        private NHSessionFactory()
        {

        }

        /// <summary>
        /// 获取单例SessionFactory
        /// </summary>
        public static ISessionFactory SessionFactory
        {
            get
            {
                if (sessionFactory == null)
                {
                    lock (lockObj)
                    {
                        if (sessionFactory == null)
                        {
                            initializeManager = new NormalInitializeNHConfiguration();
                            sessionFactory = initializeManager.Initialize();
                        }
                    }
                }
                return sessionFactory;
            }
        }

        /// <summary>
        /// 序列化一个配置对象
        /// </summary>
        /// <param name="hbmElement">配置对象</param>
        /// <returns></returns>
        public static string Serialize(HbmMapping hbmElement)
        {
            var setting = new XmlWriterSettings { Indent = true };
            var serializer = new XmlSerializer(typeof(HbmMapping));
            using (var memStream = new MemoryStream(2048))
            {
                using (var xmlWriter = XmlWriter.Create(memStream, setting))
                {
                    serializer.Serialize(xmlWriter, hbmElement);
                    memStream.Flush();
                    memStream.Position = 0;
                    var sr = new StreamReader(memStream);
                    return sr.ReadToEnd();
                }
            }
        }

        public static HbmMapping GetMapping<T>() where T : class
        {
            var orm = new ObjectRelationalMapper();
            orm.TablePerClass<T>();
            var mapper = new Mapper(orm);
            return mapper.CompileMappingFor(new[] { typeof(T) });
        }

        public static void ShowXmlMapping<T>() where T:class
        {
            var document = Serialize(GetMapping<T>());
            string fileName = typeof (T).Name + ".hbm.xml";
            File.WriteAllText(fileName, document);
            Console.Write(document);
        }

        public static void EncloseInTransaction(Action<ISession> work)
        {
            using (ISession session = SessionFactory.OpenSession())
            {
                using (ITransaction trans = session.BeginTransaction())
                {
                    try
                    {
                        work(session);
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }
    }
}